package dao

import (
	"common/biz"
	"common/logs"
	"common/utils"
	"context"
	"core/models/db"
	"core/models/entity"
	"core/repo"
	"fmt"
	"framework/msError"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"gorm.io/gorm"
	"hall/models/request"
	"time"
)

type ProductionDao struct {
	repo    *repo.Manager
	baseDao *BaseDao
}

func (d *ProductionDao) ProductionList(ctx context.Context) *[]db.ProductionHaxOneType {
	data := new([]db.ProductionHaxOneType)
	d.repo.DB.Client.WithContext(ctx).Model(&db.Production{}).Preload("Types").Find(data)
	return data
}

func (d *ProductionDao) GetProductionInfo(ctx context.Context, id uint) *db.ProductionHaxOneType {
	data := new(db.ProductionHaxOneType)
	d.repo.DB.Client.WithContext(ctx).Model(&db.Production{}).Where("id=?", id).Preload("Types").First(data)
	return data
}

func (d *ProductionDao) GetRoleProduction(ctx context.Context, uid uint, id uint) *db.RoleProduction {
	data := new(db.RoleProduction)
	d.repo.DB.Client.WithContext(ctx).Model(data).
		Where("production_id=? AND uid=?", id, uid).
		First(data)
	return data
}

func (d *ProductionDao) ProductionOpen(ctx context.Context, uid uint, production *db.ProductionHaxOneType) *msError.Error {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	var err error
	if production.ConsumeTypeID != 0 {
		//1.扣除材料
		material := new(db.WarehouseMaterialHasOneType)
		_db.Model(&db.WarehouseMaterial{}).Where("uid=? AND type_id=?", uid, production.ConsumeTypeID).Preload("Types").First(material)
		if material.Num < production.ConsumeNum {
			logs.Error("[productionHandler]用户%d ProductionOpen err:材料不足 req=%v", uid, material)
			return biz.GoodsPayError
		}
		err = tx.Model(material).Where("id=?", material.ID).Update("num", gorm.Expr("num-?", production.ConsumeNum)).Error
		if err != nil {
			logs.Error("[productionHandler]用户%d ProductionOpen err:扣除数量失败 req=%v,dbErr=%v", uid, material, err)
			return biz.SqlError
		}
		//添加材料变动记录
		collection := d.repo.Mongo.Db.Collection("material_log")
		materialLog := &entity.MaterialLog{
			UID:        uid,
			WID:        material.ID,
			TypeID:     material.TypeID,
			TypeName:   material.Types.Name,
			TypeImg:    material.Types.Img,
			TypeModule: material.Types.Module,
			LinkID:     fmt.Sprintf("%d", production.ID),
			LinkTable:  "role_production",
			Ago:        material.Num,
			Num:        -production.ConsumeNum,
			After:      material.Num - production.ConsumeNum,
			Remarks:    fmt.Sprintf("产池-开通%s号槽", production.Name),
			AddTime:    time.Now().Format(time.DateTime),
		}
		_, err = collection.InsertOne(ctx, materialLog)
		if err != nil {
			logs.Error("[productionHandler]用户%d ProductionOpen err:添加材料变动失败 req=%v,dbErr=%v", uid, materialLog, err)
			tx.Rollback()
			return biz.SqlError
		}
	}
	//添加产池
	roleProduction := &db.RoleProduction{
		ProductionID: production.ID,
		UID:          uid,
	}
	err = tx.Model(roleProduction).Create(roleProduction).Error
	if err != nil {
		logs.Error("[productionHandler]用户%d ProductionOpen err:添加产池失败 req=%v,dbErr=%v", uid, roleProduction, err)
		tx.Rollback()
		return biz.SqlError
	}
	tx.Commit()
	return nil
}

func (d *ProductionDao) ProductionInstallOfDisassembly(ctx context.Context, uid uint, req *request.ProductionInstallOfDisassembly, production *db.RoleProduction) *msError.Error {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	_mdb := d.repo.Mongo
	var err error
	log := &entity.ProductionInstallOfDisassembly{
		UID:          uid,
		ProductionID: req.ID,
		Type:         req.Type,
		AddTime:      time.Now().Format(time.DateTime),
	}
	if req.WID != 0 { //安装
		log.Status = true
		log.WID = req.WID
		switch req.Type {
		case 1: //卡牌
			if production.CardWID != 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:该产池已安装卡牌 req=%v", uid, req)
				return biz.ProductionInstallError
			}
			card := new(db.WarehouseCardHasOneType)
			_db.Model(&db.WarehouseCard{}).Where("id=? AND uid=? AND is_abandon=?", req.WID, uid, false).Preload("Types").Preload("TypeCard").First(card)
			//仓库卡牌不存在
			if card == nil || card.ID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库卡牌不存在 req=%v", uid, req)
				return biz.RequestDataError
			}
			//仓库卡牌已安装
			if card.IsUse {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库卡牌已安装 req=%v", uid, req)
				return biz.RequestDataError
			}
			//卡牌剩余产出不足
			if card.Num <= 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库卡牌剩余产出不足 req=%v", uid, req)
				return biz.NotEnoughGold
			}
			if err = tx.Model(&db.WarehouseCard{}).Where("id=?", card.ID).Update("is_use", true).Error; err != nil {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:更新仓库卡牌is_use失败 req=%v,dbErr=%v", uid, card, err)
				return biz.SqlError
			}
			production.CardWID = card.ID
			production.TotalOutput = card.TypeCard.TotalOutput
			production.SyOutput = card.Num
			production.Output = card.Rate
			if production.EquipOneWID != 0 {
				equip := new(db.WarehouseEquipHasOneType)
				_db.Model(&db.WarehouseEquip{}).Where("id=? AND uid=? AND is_abandon=?", production.EquipOneWID, uid, false).Preload("Types").Preload("Conf").First(equip)
				//production.Output += utils.DecimalFloatByInt(utils.DecimalFloatMul(utils.DecimalIntByFloat(production.Output), utils.DecimalIntDiv(equip.Conf.Increase, 100)))
				production.Output = utils.DecimalFloatByInt(utils.DecimalFloatAdd(utils.DecimalIntByFloat(production.Output), utils.DecimalFloatMul(utils.DecimalIntByFloat(card.Rate), utils.DecimalIntDiv(equip.Conf.Increase, 100))))
			}
			if production.EquipTwoWID != 0 {
				equip := new(db.WarehouseEquipHasOneType)
				_db.Model(&db.WarehouseEquip{}).Where("id=? AND uid=? AND is_abandon=?", production.EquipTwoWID, uid, false).Preload("Types").Preload("Conf").First(equip)
				//production.Output += utils.DecimalFloatByInt(utils.DecimalFloatMul(utils.DecimalIntByFloat(production.Output), utils.DecimalIntDiv(equip.Conf.Increase, 100)))
				production.Output = utils.DecimalFloatByInt(utils.DecimalFloatAdd(utils.DecimalIntByFloat(production.Output), utils.DecimalFloatMul(utils.DecimalIntByFloat(card.Rate), utils.DecimalIntDiv(equip.Conf.Increase, 100))))
			}
			log.TypeID = card.TypeID
			log.TypeName = card.Types.Name
			log.TypeImg = card.Types.Img
			break
		case 2: //装备1
			if production.EquipOneWID != 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:该产池已安装装备1 req=%v", uid, req)
				return biz.ProductionInstallError
			}
			equip := new(db.WarehouseEquipHasOneType)
			_db.Model(&db.WarehouseEquip{}).Where("id=? AND uid=? AND is_abandon=?", req.WID, uid, false).Preload("Types").Preload("Conf").First(equip)
			//仓库装备1不存在
			if equip == nil || equip.ID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备1不存在 req=%v", uid, req)
				return biz.RequestDataError
			}
			//仓库装备1已安装
			if equip.IsUse {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备1已安装 req=%v", uid, req)
				return biz.RequestDataError
			}
			if err = tx.Model(&db.WarehouseEquip{}).Where("id=?", equip.ID).Update("is_use", true).Error; err != nil {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:更新仓库装备1is_use失败 req=%v,dbErr=%v", uid, equip, err)
				return biz.SqlError
			}
			production.EquipOneWID = equip.ID
			if production.CardWID != 0 {
				card := new(db.WarehouseCardHasOneType)
				_db.Model(&db.WarehouseCard{}).Where("id=? AND uid=? AND is_abandon=?", production.CardWID, uid, false).Preload("Types").Preload("TypeCard").First(card)
				production.Output = utils.DecimalFloatByInt(utils.DecimalFloatAdd(utils.DecimalIntByFloat(production.Output), utils.DecimalFloatMul(utils.DecimalIntByFloat(card.Rate), utils.DecimalIntDiv(equip.Conf.Increase, 100))))
			}
			log.TypeID = equip.TypeID
			log.TypeName = equip.Types.Name
			log.TypeImg = equip.Types.Img
			break
		case 3: //装备2
			if production.EquipTwoWID != 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:该产池已安装装备2 req=%v", uid, req)
				return biz.ProductionInstallError
			}
			equip := new(db.WarehouseEquipHasOneType)
			_db.Model(&db.WarehouseEquip{}).Where("id=? AND uid=? AND is_abandon=?", req.WID, uid, false).Preload("Types").Preload("Conf").First(equip)
			//仓库装备2不存在
			if equip == nil || equip.ID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备2不存在 req=%v", uid, req)
				return biz.RequestDataError
			}
			//仓库装备2已安装
			if equip.IsUse {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备2已安装 req=%v", uid, req)
				return biz.RequestDataError
			}
			if err = tx.Model(&db.WarehouseEquip{}).Where("id=?", equip.ID).Update("is_use", true).Error; err != nil {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:更新仓库装备2is_use失败 req=%v,dbErr=%v", uid, equip, err)
				return biz.SqlError
			}
			production.EquipTwoWID = equip.ID
			if production.CardWID != 0 {
				card := new(db.WarehouseCardHasOneType)
				_db.Model(&db.WarehouseCard{}).Where("id=? AND uid=? AND is_abandon=?", production.CardWID, uid, false).Preload("Types").Preload("TypeCard").First(card)
				production.Output = utils.DecimalFloatByInt(utils.DecimalFloatAdd(utils.DecimalIntByFloat(production.Output), utils.DecimalFloatMul(utils.DecimalIntByFloat(card.Rate), utils.DecimalIntDiv(equip.Conf.Increase, 100))))
			}
			log.TypeID = equip.TypeID
			log.TypeName = equip.Types.Name
			log.TypeImg = equip.Types.Img
			break
		}
	} else { //拆卸
		log.Status = false
		switch req.Type {
		case 1: //卡牌
			if production.CardWID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:该产池未安装卡牌 req=%v", uid, req)
				return biz.ProductionDisassemblyError
			}
			card := new(db.WarehouseCardHasOneType)
			_db.Model(&db.WarehouseCard{}).Where("id=? AND uid=? AND is_abandon=?", production.CardWID, uid, false).Preload("Types").Preload("TypeCard").First(card)
			//仓库卡牌不存在
			if card == nil || card.ID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库卡牌不存在 req=%v", uid, req)
				return biz.RequestDataError
			}
			//仓库卡牌未安装
			if !card.IsUse {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库卡牌未安装 req=%v", uid, req)
				return biz.ProductionDisassemblyError
			}
			if err = tx.Model(&db.WarehouseCard{}).Where("id=?", card.ID).Update("is_use", false).Error; err != nil {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:更新仓库卡牌is_use失败 req=%v,dbErr=%v", uid, card, err)
				return biz.SqlError
			}
			production.CardWID = 0
			production.TotalOutput = 0
			production.SyOutput = 0
			production.Output = 0
			log.WID = production.CardWID
			log.TypeID = card.TypeID
			log.TypeName = card.Types.Name
			log.TypeImg = card.Types.Img
			break
		case 2: //装备1
			if production.EquipOneWID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:该产池未安装装备1 req=%v", uid, req)
				return biz.ProductionDisassemblyError
			}
			equip := new(db.WarehouseEquipHasOneType)
			_db.Model(&db.WarehouseEquip{}).Where("id=? AND uid=? AND is_abandon=?", production.EquipOneWID, uid, false).Preload("Types").Preload("Conf").First(equip)
			//仓库装备1不存在
			if equip == nil || equip.ID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备1不存在 req=%v", uid, req)
				return biz.RequestDataError
			}
			//仓库装备1未安装
			if !equip.IsUse {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备1未安装 req=%v", uid, req)
				return biz.RequestDataError
			}
			if err = tx.Model(&db.WarehouseEquip{}).Where("id=?", equip.ID).Update("is_use", false).Error; err != nil {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:更新仓库装备1is_use失败 req=%v,dbErr=%v", uid, equip, err)
				return biz.SqlError
			}
			production.EquipOneWID = 0
			if production.CardWID != 0 {
				card := new(db.WarehouseCardHasOneType)
				_db.Model(&db.WarehouseCard{}).Where("id=? AND uid=? AND is_abandon=?", production.CardWID, uid, false).Preload("Types").Preload("TypeCard").First(card)
				production.Output = utils.DecimalFloatByInt(utils.DecimalFloatSub(utils.DecimalIntByFloat(production.Output), utils.DecimalFloatMul(utils.DecimalIntByFloat(card.Rate), utils.DecimalIntDiv(equip.Conf.Increase, 100))))
			}
			log.WID = production.EquipOneWID
			log.TypeID = equip.TypeID
			log.TypeName = equip.Types.Name
			log.TypeImg = equip.Types.Img
			break
		case 3: //装备2
			if production.EquipTwoWID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:该产池未安装装备2 req=%v", uid, req)
				return biz.ProductionDisassemblyError
			}
			equip := new(db.WarehouseEquipHasOneType)
			_db.Model(&db.WarehouseEquip{}).Where("id=? AND uid=? AND is_abandon=?", production.EquipTwoWID, uid, false).Preload("Types").Preload("Conf").First(equip)
			//仓库装备2不存在
			if equip == nil || equip.ID == 0 {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备2不存在 req=%v", uid, req)
				return biz.RequestDataError
			}
			//仓库装备2未安装
			if !equip.IsUse {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:仓库装备2未安装 req=%v", uid, req)
				return biz.RequestDataError
			}
			if err = tx.Model(&db.WarehouseEquip{}).Where("id=?", equip.ID).Update("is_use", false).Error; err != nil {
				logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:更新仓库装备2is_use失败 req=%v,dbErr=%v", uid, equip, err)
				return biz.SqlError
			}
			production.EquipTwoWID = 0
			if production.CardWID != 0 {
				card := new(db.WarehouseCardHasOneType)
				_db.Model(&db.WarehouseCard{}).Where("id=? AND uid=? AND is_abandon=?", production.CardWID, uid, false).Preload("Types").Preload("TypeCard").First(card)
				production.Output = utils.DecimalFloatByInt(utils.DecimalFloatSub(utils.DecimalIntByFloat(production.Output), utils.DecimalFloatMul(utils.DecimalIntByFloat(card.Rate), utils.DecimalIntDiv(equip.Conf.Increase, 100))))
			}

			log.WID = production.EquipTwoWID
			log.TypeID = equip.TypeID
			log.TypeName = equip.Types.Name
			log.TypeImg = equip.Types.Img
			break
		}
	}
	err = tx.Model(production).Save(production).Error
	if err != nil {
		logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:更新产池失败 req=%v,dbErr=%v", uid, production, err)
		tx.Rollback()
		return biz.SqlError
	}
	//添加安装拆卸记录
	collection := _mdb.Db.Collection("production_log")
	_, err = collection.InsertOne(ctx, log)
	if err != nil {
		logs.Error("[productionHandler]用户%d ProductionInstallOfDisassembly err:添加安装拆卸记录失败 req=%v,dbErr=%v", uid, log, err)
		tx.Rollback()
		return biz.SqlError
	}
	tx.Commit()
	return nil
}

func (d *ProductionDao) ProductionStart(ctx context.Context, data *db.RoleProduction, output *entity.ProductionOutput) *msError.Error {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	_mdb := d.repo.Mongo
	var err error
	//1.修改改产池信息
	if err = tx.Model(data).Save(data).Error; err != nil {
		logs.Error("[productionHandler]用户%d ProductionStart err:更新产池失败 req=%v,dbErr=%v", data.UID, data, err)
		return biz.SqlError
	}
	//2.添加生产记录
	_, err = _mdb.Db.Collection("production_output_log").InsertOne(ctx, output)
	if err != nil {
		logs.Error("[productionHandler]用户%d ProductionStart err:添加生产记录失败 req=%v,dbErr=%v", data.UID, output, err)
		tx.Rollback()
		return biz.SqlError
	}
	tx.Commit()
	return nil
}

func (d *ProductionDao) ProductionEnd(ctx context.Context, data *db.RoleProduction, productionOutput *entity.ProductionOutput) error {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	_mdb := d.repo.Mongo
	var err error
	//1.检查卡牌或装备是否不满足条件需要卸下
	data.Status = false
	//data.Output = 0
	data.StarTime = 0
	data.EndTime = 0
	data.SyOutput -= utils.DecimalFloatByInt(productionOutput.Output)
	data.Receive += utils.DecimalFloatByInt(productionOutput.Output)
	cardUp := make(map[string]any)
	equipUp1 := make(map[string]any)
	equipUp2 := make(map[string]any)
	cardUp["is_new"] = false
	cardUp["num"] = gorm.Expr("num-?", productionOutput.Output)
	if data.SyOutput <= 0 {
		data.TotalOutput = 0
		data.SyOutput = 0
		data.CardWID = 0
		cardUp["is_abandon"] = true
		cardUp["is_use"] = false
	}
	if data.EquipOneWID != 0 {
		equipUp1["sy_num"] = gorm.Expr("sy_num-?", 1)
		equipUp1["is_new"] = false
		if productionOutput.EquipOneSyCount <= 0 {
			data.EquipOneWID = 0
			equipUp1["is_abandon"] = true
			equipUp1["is_use"] = false
			data.Output = utils.DecimalFloatByInt(utils.DecimalFloatSub(utils.DecimalIntByFloat(data.Output), productionOutput.EquipOneOutput))
		}
	}
	if data.EquipTwoWID != 0 {
		equipUp2["sy_num"] = gorm.Expr("sy_num-?", 1)
		equipUp1["is_new"] = false
		if productionOutput.EquipTwoSyCount <= 0 {
			data.EquipTwoWID = 0
			equipUp2["is_abandon"] = true
			equipUp2["is_use"] = false
			data.Output = utils.DecimalFloatByInt(utils.DecimalFloatSub(utils.DecimalIntByFloat(data.Output), productionOutput.EquipTwoOutput))
		}
	}
	//2.修改产池信息
	err = tx.Model(data).Save(data).Error
	if err != nil {
		err = fmt.Errorf("[productionHandler]用户%d ProductionEnd err:更新产池失败 req=%v,dbErr=%v", data.UID, data, err)
		return biz.SqlError
	}
	//3.修改卡牌信息
	if err = tx.Model(&db.WarehouseCard{}).Where("id=?", productionOutput.CardWID).Updates(cardUp).Error; err != nil {
		err = fmt.Errorf("[productionHandler]用户%d ProductionEnd err:更新卡牌信息失败 req=%v,dbErr=%v", data.UID, data, err)
		tx.Rollback()
		return biz.SqlError
	}
	//4.修改装备信息
	if len(equipUp1) > 0 {
		if err = tx.Model(&db.WarehouseEquip{}).Where("id=?", productionOutput.EquipOneWID).Updates(equipUp1).Error; err != nil {
			err = fmt.Errorf("[productionHandler]用户%d ProductionEnd err:更新装备1信息失败 req=%v,dbErr=%v", data.UID, data, err)
			tx.Rollback()
			return biz.SqlError
		}
	}
	if len(equipUp2) > 0 {
		if err = tx.Model(&db.WarehouseEquip{}).Where("id=?", productionOutput.EquipTwoWID).Updates(equipUp2).Error; err != nil {
			err = fmt.Errorf("[productionHandler]用户%d ProductionEnd err:更新装备2信息失败 req=%v,dbErr=%v", data.UID, data, err)
			tx.Rollback()
			return biz.SqlError
		}
	}
	//5.修改生产记录
	_, err = _mdb.Db.Collection("production_output_log").
		UpdateOne(
			ctx, bson.D{
				{"uid", productionOutput.UID},
				{"productionID", productionOutput.ProductionID},
				{"roleProductionID", productionOutput.RoleProductionID},
				{"cardWID", productionOutput.CardWID},
				{"status", false},
			}, bson.M{"$set": bson.M{"status": true}})
	if err != nil {
		err = fmt.Errorf("[productionHandler]用户%d ProductionEnd err:更新生产记录失败 req=%v,dbErr=%v", data.UID, data, err)
		tx.Rollback()
		return biz.SqlError
	}
	tx.Commit()
	return nil
}

func (d *ProductionDao) MongoOutputAll(ctx context.Context) *[]entity.ProductionOutput {
	collection := d.repo.Mongo.Db.Collection("production_output_log")
	whe := bson.D{
		{"status", false},
	}
	cur, err := collection.Find(ctx, whe)
	if err != nil {
		return nil
	}
	var results []entity.ProductionOutput
	for cur.Next(ctx) {
		var result entity.ProductionOutput
		err = cur.Decode(&result)
		if err == mongo.ErrNoDocuments {
			return nil
		}
		results = append(results, result)
	}
	return &results
}

func (d *ProductionDao) ProductionReceive(ctx context.Context, data *db.RoleProduction) *msError.Error {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	_mdb := d.repo.Mongo
	var err error
	var receive = data.Receive
	var typeID uint
	//1.添加材料
	material := new(db.WarehouseMaterial)
	materialType := new(db.WarehouseMaterialHasOneType)
	_db.Model(material).Where("uid=? AND type_id=?", data.UID, 11).Preload("Types").First(materialType)
	err = tx.Model(material).Where("id=?", materialType.ID).Update("num", gorm.Expr("num+?", data.Receive)).Error
	if err != nil {
		logs.Error("[productionHandler]用户%d ProductionReceive err:更新材料失败 req=%v,dbErr=%v", data.UID, data, err)
		tx.Rollback()
		return biz.SqlError
	}
	//添加材料变更记录
	materialLog := &entity.MaterialLog{
		UID:        data.UID,
		WID:        materialType.ID,
		TypeID:     materialType.TypeID,
		TypeName:   materialType.Types.Name,
		TypeImg:    materialType.Types.Img,
		TypeModule: materialType.Types.Module,
		LinkID:     fmt.Sprintf("%d", data.ID),
		LinkTable:  "role_production",
		Ago:        material.Num,
		Num:        data.Receive,
		After:      material.Num + data.Receive,
		Remarks:    "产池-领取收益",
		AddTime:    time.Now().Format(time.DateTime),
	}
	_, err = _mdb.Db.Collection("material_log").InsertOne(ctx, materialLog)
	if err != nil {
		logs.Error("[productionHandler]用户%d ProductionOpen err:添加材料变动失败 req=%v,dbErr=%v", data.UID, materialLog, err)
		tx.Rollback()
		return biz.SqlError
	}
	receive = data.Receive
	typeID = materialType.TypeID
	//2.修改产池信息
	data.Receive = 0
	err = tx.Model(data).Save(data).Error
	if err != nil {
		logs.Error("[productionHandler]用户%d ProductionReceive err:更新产池失败 req=%v,dbErr=%v", data.UID, data, err)
		return biz.SqlError
	}
	tx.Commit()
	go d.baseDao.StraightUser(data.UID, typeID, receive)
	return nil
}

func NewProductionDao(m *repo.Manager) *ProductionDao {
	return &ProductionDao{
		repo:    m,
		baseDao: NewBaseDao(m),
	}
}
